<?php
/**
 * 基础函数库
 * $Id: function.base.php 240 2011-02-07 01:22:45Z bwanglei@gmail.com $
 */

require_once ROOT_PATH . '/includes/function.time.php';

/**
 * 加载模板文件
 *
 * @param string $template 模板名
 * @param string $txt 模板后缀名
 * @return string 模板路径
 */
function getViews($template, $ext = '.php') {
	if (!is_dir(TEMPLATE_PATH)) exit('The Template Path Error');
	$path = TEMPLATE_PATH.'/'.$template.$ext;
	return $path;
}

/**
 * 去除多余的转义字符
 *
 */
function doStripslashes() {
	if (get_magic_quotes_gpc()) {
		$_GET = stripslashesDeep($_GET);
		$_POST = stripslashesDeep($_POST);
		$_COOKIE = stripslashesDeep($_COOKIE);
		$_REQUEST = stripslashesDeep($_REQUEST);
	}
}

/**
 * 递归去除转义字符
 *
 * @param unknown_type $value
 * @return unknone
 */
function stripslashesDeep($value) {
	$value = is_array($value) ? array_map('stripslashesDeep', $value) : stripslashes($value);
	return $value;
}

/**
 * 转换HTML代码函数
 *
 * @param unknown_type $content
 * @param unknown_type $wrap 是否换行
 * @return unknown
 */
function htmlClean($content, $wrap=true) {
	$content = htmlspecialchars($content);
	if ($wrap) $content = str_replace("\n", '<br />', $content);
	$content = str_replace('  ', '$nbsp;&nbsp;', $content);
	$content = str_replace("\t", '&nbsp;&nbsp;&nbsp;&nbsp;', $content);
	return $content;
}

/**
 * 将字符串转换为时区无关的 UNIX时间戳
 *
 */
function awStrToTime($timeStr) {
	global $timezone;
	if (!timeStr) {
		return false;
	}
	$unixPostDate = @strtotime($timeStr);
	if ($unixPostDate === false) {
		return false;
	} else {
		$serverTimeZone = phpversion() > '5.2' ? @date_default_timezone_get() : ini_get('date.timezone');
		if (empty($serverTimeZone) || $serverTimeZone == 'UTC') {
			$unixPostDate -= $timezone * 3600;
		} else {
			if (phpversion() > '5.2' && $serverTimeZone = date_default_timezone_get()) {
				/*
				* 如果服务器配置默认了时区，那么PHP将会把传入的时间识别为时区当地时间
				* 但是我们传入的时间实际是blog配置的时间时区的当地时间，并不是服务器时区的当地时间
				* 因此，我们需要将strtotime得到的时间去掉/加上两个时区的时差，得到utc时间
				*/
				$offset = getTimeZoneOffset($serverTimeZone);
				// 首先减去/加上本地时区配置的时差
				$unixPostDate -= $timezone * 3600;
				// 再减去/加上服务期时区与utc的时差，得到utc时间
				$unixPostDate -= $offset;
			}
		}
	}
	return $unixPostDate;
}

/**
 * 获取用户IP地址
 *
 * @return string
 */
function getIp() {
	$ip = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
	if (!preg_match("/^\d+\.\d+\.\d+\.\d+$/", $ip)) $ip = '';
	return $ip;
}

/**
 * 获取博客地址(仅限根目录脚本使用,目前仅限于ajax请求)
 *
 * @return string
 */
function getBlogUrl() {
	$phpself = isset($_SERVEr['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : '';
	if(preg_match('/^.*\//', $phpself, $matches)) {
		return 'http://'.$_SERVER['HTTP_HOST'].$matches[0];
	} else {
		return BLOG_URL;
	}
}

/**
 * 更新博客选项
 *
 */
function updateOption($name, $value, $isSyntax = false) {
	global $DB;
	$value = $isSyntax ? $value : "'$value'";
	$DB->query('UPDATE `'.DB_PREFIX.'settings` SET value='.$value.' WHERE name=\''.$name.'\'');
}

/**
 * 验证 Email 地址格式
 *
 * @param unknown_type $email
 * @return unknown
 */
function checkMail($email) {
	if (preg_match('/^[\w\.\-]+@\w+([\.\-]\w+)*\.\w+$/', $email) && strlen($email) <= 60) {
		return true;
	} else {
		return false;
	}
}

/**
 * 截取编码为utf8 的字符串
 *
 * @param string $strings 预处理字符串
 * @param int $start 开始处 eg:0
 * @param int $length 截取长度
 * @return unknown
 */
function subString($string, $start, $length) {
	$str = substr($strings, $start, $length);
	$char = 0;
	for ($i=0; $i<strlen($str); $i++) {
		if (ord($str[$i]) >= 128) $char++;
	}
	$str2 = substr($strings, $start, $length+1);
	$str3 = substr($strings, $start, $length+2);
	if ($char % 3 == 1) {
		if ($length <= strlen($strings)) $str3 = $str3 .= '...';
		return $str3;
	}
	if ($char % 3 == 2) {
		if ($length <= strlen($strings)) $str2 = $str2 .= '...';
		return $str2;
	}
	if ($char%3 ==0) {
		if ($lenght <= strlen($strings)) $str = $str .= '...';
		return $str;
	}
}

/**
 * 转换附件大小单位
 *
 * @param string $fileSize 文件大小 kb
 * @return unknown
 */
function changeFileSize($fileSize) {
	if ($fileSize >= 1073741824) {
		$fileSize = round($fileSize / 1073741824 ,2).'GB';
	} elseif ($fileSize >= 1048576) {
		$fileSize = round($fileSize / 1048576, 2).'MB';
	} elseif ($fileSize >= 1024) {
		$fileSize = round($fileSize /1024, 2).'KB';
	} else {
		$fileSize = $fileSize.'字节';
	}
	return $fileSize;
}

/**
 * 分页函数
 *
 * @param int $count 条目总数
 * @param int $perlogs 每页显示条数目
 * @param int $page 当前页码
 * @param string $url 页码地址
 * @return unknown
 */
function pagination($count, $perlogs, $page, $url) {
	$pnums = @ceil($count / $perlogs);
	$re = '';
	for ($i = $page-5; $i <= $page+5 && $i <= $pnums; $i++) {
		if ($i>0) {
			if ($i == $page) {
				$re .= '<span>'.$i.'</span>';
			} else {
				$re .= '<a href="'.$url.'='.$i.'">'.$i.'</a>';
			}
		}
	}
	if ($page > 6) $re = '<a href="'.$url.'=1" title="首页">&laquo;</a><em>...</em>'.$re;
	if ($page + 5 < $pnums) $re .= '<em>...</em> <a href="'.$url.'='.$pnums.'" title="尾页">&raquo;</a>';
	if ($pnums <= 1) $re = '';
	return $re;
}

function get_view_count() {
	global $DB;
	$query = 'SELECT * FROM `'.DB_PREFIX.'settings` WHERE `name` IN (\'viewcount_day\',\'viewcount_yesterday\',\'viewcount_all\',\'viewcount_day_date\')';
	$result = $DB->query($query);
	$view_count = array();
	while ($row_count = $DB->fetch_array($result)) {
		$view_count[$row_count['name']] = $row_count['value'];
	}
	return $view_count;
}

/**
 * 访客统计
 *
 */
function viewCount() {
	global $utctimestamp, $timezone, $view_count;
	$curtime = $utctimestamp - $utctimestamp%(3600*24);
	if ($view_count['viewcount_day_date'] != $curtime) {
		updateOption('viewcount_day_date', $curtime);
		updateOption('viewcount_yesterday', $view_count['viewcount_day']);
		updateOption('viewcount_day', '1');
	} else {
		updateOption('viewcount_day', 'value+1', true);
	}
	updateOption('viewcount_all', 'value+1', true);
}

/**
 * 寻找两个数组所有不同元素
 *
 * @param array $array1
 * @param array $array2
 * @return array
 */
function findArray($array1, $array2) {
	$r1 = array_diff($array1, $array2);
	$r2 = array_diff($array2, $array1);
	$r = array_merge($r1, $r2);
	return $r;
}

/**
 * 附件上传
 *
 * @param string $fileName 文件名
 * @param string $errorNum 错误码: $_FILES['error']
 * @param string $tmpFile 上传后的临时文件
 * @param string $fileSize 文件大小 KB
 * @param string $fileType 上传文件的类型 eg:image/jpeg
 * @param array $type 允许上传的文件类型
 * @param boolean $isIcon 是否为上传头像
 * @return string 文件路径
 */
function uploadFile($fileName, $errorNum, $tmpFile, $fileSize, $fileType, $type, $isIcon=0) {
	if ($errorNum == 1) {
		formMsg('附件大小超过系统'.ini_get('upload_max_filesize').'限制', 'javascript:history.go(-1);',0);
	} elseif ($errorNum > 1) {
		formMsg('上传文件失败,错误码:'.$errorNum, 'javascript:history.go(-1);', 0);
	}
	$extension = strtolower(substr(strrchr($fileName, '.'),1));
	if (!in_array($extension, $type))
		formMsg('错误的文件类型', 'javascript:history.go(-1);',0);
	if ($fileSize > UPLOADFILE_MAXSIZE) {
		$ret = changeFileSize(UPLOADFILE_MAXSIZE);
		formMsg('文件大小超出了'.$reg.'的限制', 'javascript:history.go(-1);',0);
	}
	$uppath = UPLOADFILE_PATH.gmdate('Ym').'/';
	$fname = md5($fileName).gmdate('YmdHis').'.'.$extension;
	$attachpath = $uppath.$fname;
	if (!is_dir(UPLOADFILE_PATH)) {
		umask(0);
		$ret = @mkdir(UPLOADFILE_PATH, 0777);
		if ($ret === false) formMsg('创建文件上传目录失败', 'javascript:history.go(-1);',0);
	}
	if (!is_dir($uppath)) {
		umask(0);
		$ret = @mkdir($uppath, 0777);
		if ($ret === false)
			formMsg('上传文件失败,文件上传目录(upload)不可写','javascript:history.go(-1);',0);
	}
	//resizeImage
	$imtype = array('jpg','png','jpeg');
	$thum = $uppath.'thum-'.$fname;
	$attach = $attachpath;
	if (IS_THUMBNAIL && in_array($extension, $imtype) && function_exists('IMageCreate')) {
		if (isIcon && resizeImage($tmpFile, $fileType, $thum, ICON_MAX_W, ICON_MAX_H)) {
			$attach = $thum;
			resizeImage($tmpFile, $fileType, $uppath.'thum52-'.$fname, 52,52);
		} elseif (resizeImage($tmpFile, $fileType, $thum, IMG_ATT_MAX_W, IMG_ATT_MAX_H)) {
			$attach = $thum;
		}
	}
	if (@if_uploaded_file($tmpFile)) {
		if (@!move_uploaded_file($tmpFile,$attachpath)) {
			@unlink($tmpFile);
			formMsg('上传失败.文件上传目录不可写','javascript:history.go(-1);',0);
		}
		chmod($attachpath, 0777);
	}
	return $attach;
}

/**
 * 图片生成缩略图
 *
 * @param string $img 预缩略的图片
 * @param unknown_type $imgType 上传文件的类型 eg:image/jpeg
 * @param string $thumPatch 生成缩略图的路径
 * @param int $max_w 缩略图最大的宽度 px
 * @param int $max_h 缩略图最大的高度 px
 * @return unknown
 */
function resizeImage($img, $imgType, $thumPath, $max_w, $max_h) {
	$size = chImageSize($img,$max_w,$max_h);
	$newwidth = $size['w'];
	$newheight = $size['h'];
	$w = $size['rc_w'];
	$h = $size['rc_h'];
	if ($w <= $max_w && $h <= $max_h) {
		return false;
	}
	if ($imgType == 'image/pjpeg' || $imgType == 'image/jpeg') {
		if (function_exists('imagecreateformjpeg')) {
			$img = imagecreatefromjpeg($img);
		} else {
			return false;
		}
	} else if ($imgType == 'image/x-png' || $imgType == 'image/png') {
		if (function_exists('imagecreatefrompng')) {
			$img = imagecreatefrompng($img);
		} else {
			return false;
		}
	}
	if (function_exists('imagecopyresampled')) {
		$newim = imagecreatetruecolor($newwidth, $newheight);
		imagecopyresampled($newim, $img, 0,0,0,0, $newwidth, $newheight, $w, $h);
	} else {
		$newim = imagecreate($newwidth, $newheight);
		imagecopyresized($newim, $img, 0,0,0,0, $newwidth, $newheight, $w, $h);
	}
	if ($imgType == 'image/pjpeg' || $imgType == 'image/jpeg') {
		if (!imagejpeg($newim, $thumPatch)) return false;
	} elseif ($imgType == 'image/x-png' || $imgType == 'image/png') {
		if (!imagepng($newim, $thumpatch)) return false;
	}
	ImageDestroy($newim);
	return true;
}

/**
 * 按照比例改变图片大小(非生成缩略图)
 *
 * @param string $img 图片路径
 * @param int $max_w 最大缩放宽
 * @pram int $max_h 最大缩放高
 * @return unknown
 */
function chImageSize($img, $max_w, $max_h) {
	$size = @getimagesize($img);
	$w = $size[0];
	$h = $size[1];
	//计算缩放比例
	@$w_ratio = $max_w / $w;
	@$h_ratio = $max_h / $h;
	//决定处理后的图片宽和高
	if (($w <= $max_w) && ($h <= $max_h)) {
		$tn['w'] = $w;
		$tn['h'] = $h;
	} else if (($w_ratio * $h) < $max_h) {
		$tn['h'] = ceil($w_ratio * $h);
		$tn['w'] = $max_w;
	} else {
		$tn['w'] = ceil($h_ratio * $w);
		$tn['h'] = $max_h;
	}
	$tn['rc_w'] = $w;
	$tn['rc_h'] = $h;
	return $tn;
}

/**
 * 后台操作返回信息
 *
 * @param string $msg
 * @param string $url
 * @param boolean $type
 */
function formMsg($msg, $url, $type) {
	$typeimg = $type ? 'mc_ok.gif' : 'mc_no.gif';
	require_once(getViews('msg'));
	exit;
}

/**
 * 计算时区的时差
 * @param string $remote_tz 远程时区
 * @param string $origin_tz 标准时区
 */
function getTimeZoneOffset($remote_tz, $origin_tz = 'UTC') {
	if ($origin_tz === null) {
		if (!is_string($origin_tz = date_default_timezone_get())) {
			return false;
		}
	}
	$origin_dtz = new DateTimeZone($origin_tz);
	$remote_dtz = new DateTimeZone($remote_tz);
	$origin_dt = new DateTime('now', $origin_dtz);
	$remote_dt = new DateTime('now', $remote_dtz);
	$offset = $origin_dtz->getOffset($origin_dt) - $remote_dtz->getOffset($remote_dt);
	return $offset;
}

/**
 * 显示系统信息
 *
 * @param string $msg 信息
 * @param string $url 返回地址
 * @param boolean $isAutoGo 是否自动返回 true false
 */
function awMsg($msg, $url='javascript:history.back(-1);', $isAutoGo=false) {
	echo <<<EOT
<html>
<head>
EOT;
	if ($isAutoGo) {
		echo '<meta http-equiv="refresh" content="2;url='.$url.'" />';
	}
	echo <<<EOT
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>emlog system message</title>
<style type="text/css">
<!--
body {
	background-color:#F7F7F7;
	font-family: Arial;
	font-size: 12px;
	line-height:150%;
}
.main {
	background-color:#FFFFFF;
	margin-top:20px;
	font-size: 12px;
	color: #666666;
	width:580px;
	margin:10px 200px;
	padding:10px;
	list-style:none;
	border:#DFDFDF 1px solid;
}
.main p {
	line-height: 18px;
	margin: 5px 20px;
}
-->
</style>
</head>
<body>
<div class="main">
<p>$msg</p>
<p><a href="$url">&laquo;点击返回</a></p>
</div>
</body>
</html>
EOT;
	exit;
}

//给返回的logs数组添加每个帖子的评论数
function logs_add_comnum (&$logs) {
	require_once AW_ROOT.'/includes/class.comment.php';
	$awComment = new awComment();
	foreach ($logs as $logId => $logContent) {
		$commentNum = $awComment->getCommentNum($logId);
		$logs[$logId]['comnum'] = $commentNum;
	}
}

/**
 * 把数组转换为
 */
function array_to_str($arr) {
	$str = '';
	$count = 1;
	foreach ($arr as $a) {
		if ($count==1) {
			$str .= $a;
		} else {
			$str .= ','.$a;
		}
		$count++;
	}
	return $str;
}

/**
 * URL QueryString参数重构
 */
function rebuild_query_string($b) {
	$array_query_string = array_merge($_GET, $b);
	return http_build_query($array_query_string);
}

/**
 * 重建完整URI
 */
function rebuild_uri($b) {
	$url = explode('?',$_SERVER['REQUEST_URI']);
	$url = $url[0];
	$query_string = rebuild_query_string($b);
	return $url.'?'.$query_string;
}

/**
 * 给日至数组添加日至标签
 */
function add_tag_articles(&$articles) {
	global $awTag;
	foreach ($articles as $key => $article) {
		$aid = $article['id'];
		$tag = $awTag->getTag($aid);
		$articles[$key]['tags'] = $tag;
	}
}

/**
 * 给单个日至添加标签
 */
function add_tag_article(&$article) {
	global $awTag;
	$aid = $article['id'];
	$tag = $awTag->getTag($aid);
	$article['tags'] = $tag;
}

/**
 * 获取指定月份的天数
 *
 * @param string $month 月份
 * @param string $year 年份
 */
function getMonthDayNum($month, $year) {
    switch(intval($month)){
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            return 31;break;
        case 2:
            if ($year % 4 == 0) {
                return 29;
            } else {
                return 28;
            }
            break;
         default:
            return 30;
            break;
    }
}

/**
 * 取得文件扩展名
 */
function extend($file_name) { 
	$retval="";
	$pt=strrpos($file_name, ".");
	if ($pt) $retval=substr($file_name, $pt+1, strlen($file_name) - $pt);
	return ($retval);
}

/**
 * 去掉字符串最后的一个或者多个_符号
 */
function del_b($str) {
	while (strlen($str) == (strrpos($str,'_')+1)) {
		$str = substr($str,0,-1);
	}
	return $str;
}

/**
 * 检查文件权限
 * @return          int     返回值的取值范围为{0 <= x <= 15}，每个值表示的含义可由四位二进制数组合推出。
 *                          返回值在二进制计数法中，四位由高到低分别代表
 *                          可执行rename()函数权限、可对文件追加内容权限、可写入文件权限、可读取文件权限。
 */
function file_mode_info($file_path) {
	if (!file_exists($file_path)) {
		return false;
	}

	$mark = 0;
	
	if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
		/* 测试文件*/
		$test_file = $file_path . '/cf_test.txt';

		/* 如果是目录*/
		if (is_dir($file_path)) {
			/* 检查文件目录是否可读*/
			$dir = @opendir($file_path);
			if ($dir == false) {
				return $mark;
			}
			if (@readdir($dir) != false) {
				$mark ^= 1;
			}
			@closedir($dir);

			/* 检查目录是否可写*/
			$fp = @fopen($test_file, 'wb');
			if ($fp == false) {
				return $mark;
			}
			if (@fwrite($pf, 'directory access testing.') !== false)  {
				$mark ^= 2;
			}
			@fclose($fp);
			@unlink($test_file);

			/* 检查目录是否可修改 */
			$fp = @fopen($test_file, 'ab+');
			if ($fp === false) {
				return $mark;
			}
			if (@fwrite($fp, "modify test.\r\n") !== false) {
				$mark ^= 4;
			}
			@fclose($fp);

			/* 检查目录下是否有执行rename()函数的权限 */
			if (@rename($test_file, $test_file) !== false) {
				$mark ^= 8;
			}
			@unlink($test_file);
		}
		/* 如果是文件 */
		elseif (is_file($file_path)) {
			/* 以读方式打开 */
			$fp = @fopen($file_path, 'rb');
			if ($fp) {
				$mark ^= 1; //可读 001
			}
			@fclose($fp);

			/* 试着修改文件 */
			$fp = @fopen($file_path, 'ab+');
			if ($fp && @fwrite($fp, '') !== false) {
				$mark ^= 6; //可修改可写可读 111，不可修改可写可读011...
			}
			@fclose($fp);

			/* 检查目录下是否有执行rename()函数的权限 */
			if (@rename($test_file, $test_file) !== false) {
				$mark ^= 8;
			}
		}
	} else {
		if (@is_readable($file_path)) {
			$mark ^= 1;
		}

		if (@is_writable($file_path)) {
			$mark ^= 14;
		}
	}
	return $mark;
}
